home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <limits.h>
- #include "../misc/misc.h"
- #include "xconf.h"
- #include "components.h"
-
- PUBLIC COMPONENT::COMPONENT(
- const char *manuf_id,
- const char *model_id,
- XCONFIG *_xconfig,
- NOTICE *_notice,
- ACTION *_action)
- : PAIRES (manuf_id,model_id)
- {
- xconfig = _xconfig;
- notice = _notice;
- action = _action;
- }
-
- PUBLIC COMPONENTS::COMPONENTS()
- {
- max_component = 0;
- nb_component = 0;
- tb_component = NULL;
- max_xconfig = 0;
- nb_xconfig = 0;
- tb_xconfig = NULL;
- max_notice = 0;
- nb_notice = 0;
- tb_notice = NULL;
- }
-
- PUBLIC VIRTUAL COMPONENTS::~COMPONENTS()
- {
- for (int i=0; i<nb_component; i++) delete tb_component[i];
- free (tb_component);
- for (i=0; i<nb_xconfig; i++) delete tb_xconfig[i];
- free (tb_xconfig);
- for (i=0; i<nb_notice; i++) delete tb_notice[i];
- free (tb_notice);
- }
-
- /*
- Add a new component to the list
- */
- PUBLIC void COMPONENTS::add (COMPONENT *comp)
- {
- if (nb_component == max_component){
- max_component += 50;
- tb_component = (COMPONENT**)realloc(tb_component
- ,sizeof(XCONFIG*)*max_component);
- }
- tb_component[nb_component++] = comp;
- }
- /*
- Add a new partial Xconfig to the list
- */
- PUBLIC void COMPONENTS::add (XCONFIG *xconf)
- {
- if (nb_xconfig == max_xconfig){
- max_xconfig += 10;
- tb_xconfig = (XCONFIG**)realloc(tb_xconfig
- ,sizeof(XCONFIG*)*max_xconfig);
- }
- tb_xconfig[nb_xconfig++] = xconf;
- }
- /*
- Add a new notice to the list
- */
- PUBLIC void COMPONENTS::add (NOTICE *notice)
- {
- if (nb_notice == max_notice){
- max_notice += 10;
- tb_notice = (NOTICE**)realloc(tb_notice
- ,sizeof(NOTICE*)*max_notice);
- }
- tb_notice[nb_notice++] = notice;
- }
-
- /*
- Read and parse a xconf file
- */
- PUBLIC int COMPONENTS::read (const char *fname)
- {
- int ret = -1;
- FILE *fin = xconf_fopen (fname,"r");
- if (fin != NULL){
- char buf[300];
- ret = 0;
- XCONFIG *xconfig = NULL;
- NOTICE *notice = NULL;
- ACTION *action = NULL;
- char manuf[100];
- manuf[0] = '\0';
- char doing_xconfig = 0; // Parsing between @ paires ?
- char doing_notice = 0; // Parsing between ! paires ?
- char doing_action = 0; // Parsing between $ paires ?
- int noline = 0;
- while (fgets(buf,sizeof(buf)-1,fin)!= NULL){
- noline++;
- str_strip (buf,buf);
- /* #Specification: data files / *.xconf
- file *.xconf are lists of hardware components
- (either screen or adaptor). The format is simple
- although not so visual.
-
- -manufacturer ID
- @
- parts of an Xconfig file useful for the
- next component model following this section
- @
- model ID
- Another model sharing the same configuration
- @
- A different Xconfig setup
- @
- !
- A notice applying to following component
- The notice hold true until a new notice
- is entered.
- !
- $
- A script to execute to make the configuration
- effective. The script will be valid for
- all following model
- $
- another model ID
- -another manufacturer
-
- Note also that the configurator merge several *.xconf files.
- For example, I expect that a *.xconf file will be bundle
- with each specific X server available (Mach32 SVGA etc...)
-
- Here is a small example
-
- -ATI
- @
- ACCEL
- Clocks 100.0 126.0 92.4 36.0 50.35 56.64 0 44.90
- 135.0 32.0 110.0 80.0 39.91 49.90 75.0 65.0
- Option "sw_cursor"
- Modes "1024x768"
- @
- $
- ln -sf /usr/X11R6/bin/XF86_Mach32 /usr/X11R6/bin/X
- $
- vlb Mach32
- !
- Please note that the busmouse on the Mach8 and Mach32
- has to be configurer on IRQ 5.
- !
- Mach32 ultra
- !
- !
- -Genoa
- .
- .
-
- Line beginning with a # is a comment. Empty lines are
- allowed.
- */
- /* #Specification: data files / *.xconf / order
- There is no need to put all products of a manufacturer
- in the same section. Xconfigs may appear anywhere
- and are shared between manufacturer. The following is
- valid.
-
- @
- long Xconfig configuration
- .
- @
- -manuf1
- model1
- model2
- -manuf2
- model4
- @
- other long configuration
- @
- -manuf1
- model3
- */
- char *pt = buf;
- while (isspace (*pt)) pt++;
- if (pt[0] != '#' && pt[0] != '\0'){
- if (pt[0] == '-'){
- pt++;
- while (isspace(*pt)) pt++;
- strcpy (manuf,pt);
- }else if (pt[0] == '@'){
- if (doing_xconfig){
- doing_xconfig = 0;
- }else{
- doing_xconfig = 1;
- xconfig = new XCONFIG;
- add (xconfig);
- }
- }else if (pt[0] == '!'){
- if (doing_notice){
- doing_notice = 0;
- }else if (pt[1] == '!'){
- /* #Specification: data files / *.xconf / null notice
- A line with !! indicate a null notice until
- a new one is seen.
-
- A line with $$ indicate a null action
- */
- notice = NULL;
- }else{
- doing_notice = 1;
- notice = new NOTICE;
- add (notice);
- }
- }else if (pt[0] == '$'){
- if (doing_action){
- doing_action = 0;
- }else if (pt[1] == '$'){
- action = NULL;
- }else{
- doing_action = 1;
- action = new ACTION;
- add (action);
- }
- }else if (doing_xconfig){
- xconfig->parse (buf,fname,noline);
- }else if (doing_notice){
- notice->add (pt);
- }else if (doing_action){
- action->add (pt);
- }else{
- // This is a model ID
- add (new COMPONENT (manuf,pt,xconfig,notice,action));
- }
- }
- }
- fclose (fin);
- }
- return ret;
- }
- static int cmp (const void **pp1, const char **pp2)
- {
- COMPONENT *p1 = (COMPONENT *)(*pp1);
- COMPONENT *p2 = (COMPONENT *)(*pp2);
- int ret = strcmp(p1->keyw,p2->keyw);
- if (ret == 0) ret = strcmp(p1->arg,p2->arg);
- return ret;
- }
- /*
- Sort all COMPONENT by manuf_id and model_id.
- */
- PUBLIC void COMPONENTS::sort ()
- {
- qsort (tb_component,nb_component,sizeof(COMPONENT*),cmp);
- }
-
- /*
- Print all COMPONENTS with the same format as input, mostly to debug
- */
- PUBLIC void COMPONENTS::print (FILE *fout)
- {
- XCONFIG *xconfig=NULL;
- NOTICE *notice=NULL;
- ACTION *action=NULL;
- char manuf[100];
- manuf[0] = '\0';
- for (int i=0; i<nb_component; i++){
- COMPONENT *comp = tb_component[i];
- if (strcmp(comp->keyw,manuf)!=0){
- strcpy (manuf,comp->keyw);
- fprintf (fout,"-%s\n",manuf);
- }
- if (comp->xconfig != xconfig){
- xconfig = comp->xconfig;
- fprintf (fout,"\t@\n");
- xconfig->print (fout,2);
- fprintf (fout,"\t@\n");
- }
- if (comp->notice != notice){
- notice = comp->notice;
- fprintf (fout,"\t!\n");
- notice->print (fout,2);
- fprintf (fout,"\t!\n");
- }
- if (comp->action != action){
- action = comp->action;
- fprintf (fout,"\t$\n");
- action->print (fout,2);
- fprintf (fout,"\t$\n");
- }
- fprintf (fout,"\t%s\n",comp->arg);
- }
- }
-
- /*
- Encode de component ids in a string table so it fit the dialog system.
- tb[optnum*2] = manuf_id;
- tb[optnum*2+1] = model_id;
-
- Return the number of components placed in tbopt2, not the number of
- strings.
- */
- PUBLIC int COMPONENTS::setmenu (
- char *tbopt2[])
- {
- int nb = 0;
- char *manuf = NULL;
- for (int i=0; i<nb_component; i++){
- COMPONENT *comp = tb_component[i];
- if (manuf == NULL || strcmp(comp->keyw,manuf)!=0){
- manuf = comp->keyw;
- tbopt2[nb++] = manuf;
- }else{
- tbopt2[nb++] = " ";
- }
- tbopt2[nb++] = comp->arg;
- }
- tbopt2[nb] = NULL;
- return nb_component;
- }
-
- PUBLIC COMPONENT *COMPONENTS::item(int no)
- {
- COMPONENT *ret = NULL;
- if (no >= 0 && no < nb_component) ret = tb_component[no];
- return ret;
- }
- #ifdef TEST
-
- int main (int argc, char *argv[])
- {
- COMPONENTS comp;
- comp.read ("adaptors.xconf");
- comp.sort ();
- comp.print (stdout);
- return 0;
- }
-
- #endif
-
-